<?php
/**
 * Управление изображениями
 * 
 * @category Phorm
 * @package Image
 * @name /Phorm/Image.php
 * @copyright phorm.ru
 * @since 02.03.2010
 * @author vladimir@kachalov.net
 */

class Phorm_Image {

	/**
	 * Путь и имя файла исходного изображения
	 * @var string
	 */
	private $_filename;
	
	/**
	 * Ширина исходного изображения в пикселях
	 * @var int
	 */
	private $_width;
	
	/**
	 * Высота исходного изображения в пикселях
	 * @var int
	 */
	private $_height;
	
	/**
	 * Mime-Type исходного изображения
	 * @var string
	 */
	private $_mimetype;

	/**
	 * Ресурс/Объект изображения
	 * @var resource
	 */
	private $_image;

	/**
	 * Расширение исходного изображения
	 * @var string
	 */
	private $_extension;

	/**
	 * Конструктор
	 * 
	 * @param string $filename Путь к изображению
	 * 
	 * @return null
	 */

	function __construct($filename) {
		
		require_once 'Zend/Validate/Exception.php';

		// Проверяем существование файла

		if(file_exists($filename)) {

			// Проверяем, является ли файл изображением

			if($imageinfo = getimagesize($filename)) {

				if(in_array($imageinfo["mime"],array("image/gif","image/png","image/jpeg"))) {

					$this->_filename = $filename;
					$this->_width = $imageinfo[0];
					$this->_height = $imageinfo[1];
					$this->_mimetype = $imageinfo["mime"];
					$this->_image = $this->Create();

				} else {

					throw new Zend_Exception("'$filename' is not image");

				}

			} else {

				throw new Zend_Exception("'$filename' is not image");

			}


		} else {

			throw new Zend_Exception("Image not found from '$filename'");

		}

	}


	/**
	 * Возвращает информацию об изображении
	 * 
	 * @return array
	 */

	function getImageInfo() {

		return array(
			"filename" => $this->_filename,
			"width"    => $this->_width,
			"height"   => $this->_height,
			"mimetype" => $this->_mimetype
		);

	}


	/**
	 * Создает объект изображения для дальнейших модификаций и определяет расширение файла
	 * 
	 * @return resource
	 */

	function Create() {

		switch ($this->_mimetype) {

			case "image/gif":
				$this->_extension = "gif";
				return imagecreatefromgif($this->_filename);
				break;

			case "image/png":
				$this->_extension = "png";
				return imagecreatefrompng($this->_filename);
				break;

			case "image/jpeg":
				$this->_extension = "jpg";
				return imagecreatefromjpeg($this->_filename);
				break;

		}

		return false;

	}


	/**
	 * Удаляет объект изображения
	 * 
	 * @return null
	 */

	function Destroy() {

		imagedestroy($this->_image);

	}


	/**
	 * Возвращает расширение текущего изображения
	 * 
	 * @return string
	 */

	function getExtension() {

		return $this->_extension;

	}


	/**
	 * Пропорциональное изменение размера изображения
	 * 
	 * @param int $width Ширина
	 * @param int $height Высота
	 * @param string $crop Тип обрезания/заливки изображения
	 * 
	 * @return Phorm_Image
	 */

	function Resize($width,$height,$crop = false) {

		if($this->_width>$width || $this->_height>$height) {

			/**
			 * Определяем коэффициент уменьшения изображения
			 */

			if($this->_width>=$this->_height && $width==0) {
				$ratio = $this->_height/$height;
			} elseif ($this->_width<$this->_height && $height==0) {
				$ratio = $this->_width/$width;
			} elseif ($this->_width>=$this->_height && $width>0) {
				$ratio = $this->_width/$width;
			} elseif ($this->_width<$this->_height && $height>0) {
				$ratio = $this->_height/$height;
			} else {
				return $this;
			}

			/**
			 * Определяем параметры обрезания или заливки
			 */

			if($crop && in_array($crop,array('fill','center','left','right')) && $width>0 && $height>0) {

				// Требуется обрезание

				switch ($crop) {

					// Заливка полей

					case "fill":

						$im = imagecreatetruecolor($width,$height);
						//$white = imagecolorallocate($im, 255, 255, 255);
						//imagefill($im, 0, 0, $white);
						imagesavealpha($im, true);
						imagefill($im, 0, 0, imagecolorallocatealpha($im,0,0,0,127));

						$dst_w = ceil($this->_width/$ratio);
						$dst_h = ceil($this->_height/$ratio);
						$dst_x = ceil(($width-$dst_w)/2);
						$dst_y = ceil(($height-$dst_h)/2);

						imagecopyresampled($im, $this->_image, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $this->_width, $this->_height);

						break;

						// Вырубка по центру

					case "center" || "left" || "right":

						$ratio = $this->_width>$this->_height ? $this->_height/$height : $this->_width/$width;

						$dst_w = ceil($this->_width/$ratio);
						$dst_h = ceil($this->_height/$ratio);
						$dst_x = ceil(($width-$dst_w)/2);
						$dst_y = ceil(($height-$dst_h)/2);

						$im = imagecreatetruecolor($width,$height);
						imagesavealpha($im, true);
						imagefill($im, 0, 0, imagecolorallocatealpha($im,0,0,0,127));
						imagecopyresampled($im, $this->_image, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $this->_width, $this->_height);

						break;

				}

				$this->_width  =  $width;
				$this->_height = $height;

			} else {

				// Обрезание не требуется

				$im = imagecreatetruecolor(ceil($this->_width/$ratio),ceil($this->_height/$ratio));
				imagesavealpha($im, true);
				imagefill($im, 0, 0, imagecolorallocatealpha($im,0,0,0,127));
				
				$dst_w = ceil($this->_width/$ratio);
				$dst_h = ceil($this->_height/$ratio);

				imagecopyresampled($im, $this->_image, 0, 0, 0, 0, $dst_w, $dst_h, $this->_width, $this->_height);

				$this->_width  = ceil($this->_width/$ratio);
				$this->_height = ceil($this->_height/$ratio);

			}

			$this->_image  = $im;

		}

		return $this;

	}


	/**
	 * Сохранение изображения
	 * 
	 * @param string $filename  Куда сохранять изображение. 
	 * 							Тип изображения зависит от расширения, 
	 * 							если расширение не указано, то на основе исходника
	 *
	 * @return Phorm_Image
	 */

	function Save($filename) {

		if(preg_match("#\.(gif|png|jpg|jpe|jpeg)$#i",$filename,$ext)) {

			$extension = $ext[1];

			$filename = preg_replace("#\.(gif|png|jpg|jpe|jpeg)$#i","",$filename);

		} else {

			$extension = $this->_extension;

		}
		
		$extension = strtolower($extension);

		switch ($extension) {

			case "gif":
				imagegif($this->_image,$filename.".".$extension);
				break;

			case "png":
				imagepng($this->_image,$filename.".".$extension);
				break;

			case "jpg" || "jpe" || "jpeg":
				imagejpeg($this->_image,$filename.".".$extension,90);
				break;

		}

		return $this;

	}


}